/*
 * Metrics.cpp
 *
 *  Created on: 10/12/2008
 *      Author: fernando
 */

#include "Metrics.h"
#include <math.h>
#include <allegro.h>

namespace core {

Metrics::Metrics() {
	_rotation = PI * 0.25;
	_elevation = 1.1;
	_zoom = 30.0;
}

Metrics::~Metrics() {
}

void Metrics::zoom(float zoom) {
	_zoom = zoom;
}

void Metrics::centre(Point& point) {
	centre(point.x, point.y);
}

void Metrics::centre(float x, float y) {
	_centre.x = x;
	_centre.y = y;
}

void Metrics::update() {

	/* Rotação */
	_x_axis.x = cos(_rotation) * 1 - sin(_rotation) * 0;
	_x_axis.y = sin(_rotation) * 1 + cos(_rotation) * 0;
	_z_axis.x = cos(_rotation) * 0 - sin(_rotation) * 1;
	_z_axis.y = sin(_rotation) * 0 + cos(_rotation) * 1;

	/* Elevação */
	_x_axis.y *= cos(_elevation);
	_z_axis.y *= cos(_elevation);

	/* Câmera, assumindo que a câmera nunca gira em torno do seu eixo. */
	_y_axis.x = 0.0;
	_y_axis.y = sin(_elevation);

	/* Zoom */
	_x_axis.x *= _zoom;
	_x_axis.y *= _zoom;
	_z_axis.x *= _zoom;
	_z_axis.y *= _zoom;
	_y_axis.x *= _zoom;
	_y_axis.y *= _zoom;
}

void Metrics::toScreen(Point& from, Point& to) const {
	toScreen(from.x, from.y, 0.0, to);
}

void Metrics::toScreen(Vertex& from, Point& to) const {
	toScreen(from.x, from.y, from.z, to);
}

void Metrics::toScreen(float x, float y, float z, Point& to) const {
	/* Corrigindo o vértice. */
	x -= _centre.x;
	y -= _centre.y;

	to.x = x * _x_axis.x + y * _z_axis.x + z * _y_axis.x;
	to.y = x * _x_axis.y + y * _z_axis.y + z * _y_axis.y;

	to.x += SCREEN_W * 0.5;
	to.y += SCREEN_H * 0.5;
}

}
